<script lang="ts" setup>
import { ref, onMounted, onUnmounted, watch, reactive, nextTick, computed } from "vue"
import { ElInput, ElForm, ElFormItem, ElButton, ElMessage } from "element-plus"
import type { FormInstance } from 'element-plus'
import Code from "#/components/common/code.vue"
import { getVerificationCodeApi, getEmailCodeApi, registerApi, resetPasswordApi } from '#/api';
import { useRouter, useRoute } from 'vue-router';
import setPublicCode from "#/utils/setPublicKey"
import { TelMatcher, EmailMatcher, idCardRegex, PasswordRegex } from "#/utils/constants"
import regSucess from "#/assets/images/register-sucess.png"
import { DEFAULT_HOME_PATH, LOGIN_PATH } from '#/utils/constants';
import { getVoiceVerificationCodeApi } from "#/api/core/auth"
import { $t } from '@vben/locales';
import { useCodeName } from "#/hooks/useCodeName"
import { agreementContentText, privacyContentText } from "./modules/const"
import SliderDialog from "#/components/slider-dialog.vue"
import { getVoiceVerificationOpenCodeApi, getVerificationOpenCodeApi } from "#/api/core/auth"

defineOptions({ name: 'Register' });
const route = useRoute();
const activeType = ref<string>(route?.name === 'ResetPassword' ? 'reset' : 'register');
const titleTxt = ref<string>(route?.name === 'ResetPassword' ? $t('register.resetPassword') : $t('register.welcomeTitle'))
const { isVoiceCode, codeBtnName, codeInputPlaceholder } = useCodeName()
const trustPact = ref(false)
const isReg = ref(true)
const passwordErrMsg = $t('register.passwordFormatError')
const formRef = ref<FormInstance>()
let intervalId: number | any;
const timeLeft = ref(5);
// 定时器ID存储，用于组件卸载时清理
let mountTimeoutId: number | any;
let clearIntervalTimeoutId: number | any;
let codeFocusTimeoutId: number | any;
let passwordFocusTimeoutId: number | any;
let confirmPasswordFocusTimeoutId: number | any;
// 表单key，用于强制重新渲染
const formKey = ref(0)
// 弹窗控制变量
const showDialog = ref(false)
const dialogType = ref<'agreement' | 'privacy'>('agreement')

// 富文本内容
const agreementContent = agreementContentText
const privacyContent = privacyContentText
const codeRef = ref<any>(null);
const router = useRouter()
const EMAIL = 'email';
const PHONE = 'phone';
const regPasswordKey = ref(0)
const regConfirmPasswordKey = ref(0)
const sliderDialogVisible = ref(false)
const sliderDialogRef = ref<any>(null)
let codeCallBack: Function | null = null;
const ruleForm = ref<{
  [key: string]: any,
  confirmPassword?: string
}>({
  [PHONE]: "",
  phoneCode: '',
  loginPassword: "",
  confirmPassword: "",
  // nameCn: "",
  // idCard: "",
  // [EMAIL]: '',
  // emailCode: ''
})
const passwordCheck = (val: string) => {
  return PasswordRegex.test(val)
}
const rules = reactive({
  [PHONE]: [
    { required: true, pattern: TelMatcher, message: $t('common.phonePhTxt'), trigger: 'blur' },
  ],
  phoneCode: [
    { required: true, message: codeInputPlaceholder, trigger: 'blur' },
  ],
  loginPassword: [
    {
      required: true, validator: (rule: any, value: any, callback: any) => {
        if (!value) {
          callback(new Error($t('common.inputPhTxt', [$t('login.password')])))
          return
        }
        if (!passwordCheck(value)) {
          callback(new Error(passwordErrMsg))
          return
        }
        if (ruleForm.value.confirmPassword && value !== ruleForm.value.confirmPassword) {
          // callback(new Error($t('register.passwordMismatchError')))
          formRef.value?.validateField(['confirmPassword'])
        }

        // 验证通过，清除确认密码的错误并通过验证
        formRef.value?.clearValidate(['confirmPassword'])

        callback()
      }, trigger: 'blur'
    },
  ],
  confirmPassword: [
    {
      required: true, validator: (rule: any, value: any, callback: any) => {
        if (!value) {
          callback(new Error($t('common.inputPhTxt', [$t('register.confirmPassword')])))
          return
        }
        if (!passwordCheck(value)) {
          callback(new Error(passwordErrMsg))
          return
        }
        if (ruleForm.value.loginPassword && value !== ruleForm.value.loginPassword) {
          callback(new Error($t('register.passwordMismatchConfirmError')))
          return
        }
        // 验证通过，清除登录密码的错误并通过验证
        formRef.value?.clearValidate(['loginPassword'])
        callback()
      }, trigger: 'blur'
    },
  ],
  // nameCn: [
  //   { required: true, message: $t('common.inputPhTxt', [$t('common.nameTxt')]), trigger: 'blur' },
  // ],
  // idCard: [
  //   { required: true, pattern: idCardRegex, message: $t('common.idCardPhTxt'), trigger: 'blur' },
  // ],
  // email: [
  //   { required: true, pattern: EmailMatcher, message: $t('common.emailPhTxt'), trigger: 'blur' },
  // ],
  // emailCode: [{ required: true, message: $t('common.inputPhTxt', [$t('common.emailCodeTxt')]), trigger: 'blur' }]
})

// 注册成功后需要判断用户身份，是跳转到客户端还是服务端
const register = () => {
  if (!formRef) return
  formRef.value?.validate((valid) => {
    if (valid) {
      //看是否勾选了隐私政策
      if (activeType.value === 'register' && !trustPact.value) {
        ElMessage.error($t('register.agreementRequiredError'))
        return
      }
      let data = { ...ruleForm.value }
      delete data.confirmPassword
      data.loginPassword = setPublicCode(data.loginPassword)
      // data.idCard = setPublicCode(data.idCard)
      const api = activeType.value === 'register' ? registerApi : resetPasswordApi
      api(data).then(() => {
        // ElMessage.success("注册成功")
        // router.push('/auth/login')
        if (activeType.value === 'register') {
          isReg.value = false
        } else {
          ElMessage.success($t('register.resetPasswordSuccess'))
          router.push('/auth/login')
        }
      })
    }

  })
}

const handleVerifySuccess = async (data: string) => {
  try {
    codeCallBack?.();
    if (isVoiceCode.value) {
      await getVoiceVerificationOpenCodeApi({ phoneNumber: ruleForm.value.phone, captchaKey: data })
    } else {
      await getVerificationOpenCodeApi({ phoneNumber: ruleForm.value.phone, captchaKey: data })
    }
  } catch (error) {
    console.error('验证失败:', error);
  }
}

const getCode = (callback: Function) => {
  formRef.value?.validateField([PHONE], (valid) => {
    if (valid) {
      codeCallBack = callback
      sliderDialogVisible.value = true
    }
  })
}

const clear = () => {
  clearInterval(intervalId);
}

watch(() => isReg.value, (n, o) => {
  if (!n) {
    startCountdown()
  } else {
    clear()
  }
})

const startCountdown = () => {
  intervalId = setInterval(() => {
    if (timeLeft.value > 0) {
      timeLeft.value--;
    } else {
      clear()
      toHome(LOGIN_PATH)
    }
  }, 1000);
};

const toHome = (path: string) => {
  router.push(path)
}

onMounted(() => {
  isReg.value = true
  formRef.value?.resetFields()

  // 强化的密码防自动填充措施
  mountTimeoutId = setTimeout(() => {
    const inputs = document.querySelectorAll('input[type="text"], input[type="password"]')
    inputs.forEach((input: any) => {
      // 只在页面刚加载且Vue数据都为空时清除自动填充值
      if (input.value && input.value.length > 0 &&
        !ruleForm.value.phone &&
        !ruleForm.value.phoneCode &&
        !ruleForm.value.loginPassword &&
        !ruleForm.value.confirmPassword) {
        input.value = ''
      }

      // 添加防自动填充属性
      input.setAttribute('data-lpignore', 'true')
      input.setAttribute('data-1p-ignore', 'true')

      // 专门处理密码输入框
      if (input.type === 'password') {
        // 添加额外的防自动填充属性
        input.setAttribute('data-form-type', 'search')
      }
    })

    // 只在页面刚加载的短时间内检查并清除明显的浏览器自动填充
    const passwordCheckInterval = setInterval(() => {
      const passwordInputs = document.querySelectorAll('input[type="password"]')
      passwordInputs.forEach((input: any, index: number) => {
        // 更严格的条件：只在Vue数据为空且DOM值异常长时才认为是自动填充
        // 检查登录密码 - 只在Vue数据为空且DOM值异常时清除
        if (index === 0 && input.value && input.value.length > 15 &&
          !ruleForm.value.loginPassword &&
          // 确保不是用户正在输入（通过检查焦点状态）
          document.activeElement !== input) {
          console.log('检测到可能的自动填充登录密码，已清除')
          input.value = ''
          regPasswordKey.value++
        }
        // 检查确认密码
        if (index === 1 && input.value && input.value.length > 15 &&
          !ruleForm.value.confirmPassword &&
          document.activeElement !== input) {
          console.log('检测到可能的自动填充确认密码，已清除')
          input.value = ''
          regConfirmPasswordKey.value++
        }
      })
    }, 1000)

    // 1.5秒后停止检查，避免干扰用户正常输入
    clearIntervalTimeoutId = setTimeout(() => {
      clearInterval(passwordCheckInterval)
    }, 1500)
  }, 200)
})

onUnmounted(() => {
  isReg.value = false
  clear()

  // 清理所有setTimeout定时器
  if (mountTimeoutId) {
    clearTimeout(mountTimeoutId)
  }
  if (clearIntervalTimeoutId) {
    clearTimeout(clearIntervalTimeoutId)
  }
  if (codeFocusTimeoutId) {
    clearTimeout(codeFocusTimeoutId)
  }
  if (passwordFocusTimeoutId) {
    clearTimeout(passwordFocusTimeoutId)
  }
  if (confirmPasswordFocusTimeoutId) {
    clearTimeout(confirmPasswordFocusTimeoutId)
  }

})

const isDisabled = computed(() => {
  if (ruleForm.value.phone &&
    ruleForm.value.phoneCode && ruleForm.value.loginPassword
    && ruleForm.value.confirmPassword
  ) return false
  return true
})

const toLogin = () => {
  router.push('/auth/login')
}

// 滚动到顶部的方法
const scrollToTop = () => {
  const dialogContent = document.querySelector('.dialog-content')
  if (dialogContent) {
    dialogContent.scrollTop = 0
  }
}

// 打开使用协议弹窗
const openAgreementDialog = () => {
  dialogType.value = 'agreement'
  showDialog.value = true
  // 使用 nextTick 确保 DOM 更新后再滚动
  nextTick(() => {
    scrollToTop()
  })
}

// 打开隐私政策弹窗
const openPrivacyDialog = () => {
  dialogType.value = 'privacy'
  showDialog.value = true
  // 使用 nextTick 确保 DOM 更新后再滚动
  nextTick(() => {
    scrollToTop()
  })
}

// 关闭弹窗
const closeDialog = () => {
  showDialog.value = false
}

const getVoiceCode = (value: boolean, event?: Event) => {
  if (codeRef.value.isCounting) return;

  // 阻止事件冒泡和默认行为
  if (event) {
    event.preventDefault()
    event.stopPropagation()
  }

  // 切换状态
  isVoiceCode.value = value
  ruleForm.value.phoneCode = ''

  // 强制重新渲染表单，彻底清除所有校验状态
  formKey.value++
}

// 验证码输入框焦点处理
const handleCodeFocus = () => {
  // 验证码获得焦点时清除任何可能的自动填充
  // 清理之前的定时器
  if (codeFocusTimeoutId) {
    clearTimeout(codeFocusTimeoutId)
  }
  codeFocusTimeoutId = setTimeout(() => {
    if (ruleForm.value.phoneCode && ruleForm.value.phoneCode.length > 6) {
      // 清除可能的错误自动填充（验证码通常不超过6位）
      ruleForm.value.phoneCode = ''
    }
  }, 50)
}

// 验证码输入处理
const handleCodeInput = (value: string) => {
  // 只允许数字输入
  const numericValue = value.replace(/[^0-9]/g, '')
  if (numericValue !== value) {
    ruleForm.value.phoneCode = numericValue
  }

  // 限制长度
  if (numericValue.length > 10) {
    ruleForm.value.phoneCode = numericValue.slice(0, 10)
  }
}

// 注册密码输入框焦点处理
const handleRegPasswordFocus = () => {
  // 只在获得焦点时且明显是浏览器自动填充的情况下清除
  // 清理之前的定时器
  if (passwordFocusTimeoutId) {
    clearTimeout(passwordFocusTimeoutId)
  }
  passwordFocusTimeoutId = setTimeout(() => {
    const passwordInputs = document.querySelectorAll('input[type="password"]')
    const loginPasswordInput = passwordInputs[0] as HTMLInputElement
    if (loginPasswordInput && loginPasswordInput.value &&
      !ruleForm.value.loginPassword &&
      loginPasswordInput.value.length > 20 && // 提高阈值，只清除明显异常长的自动填充
      // 确保是刚获得焦点且之前Vue数据为空
      loginPasswordInput === document.activeElement) {
      // 只清除明显的浏览器自动填充
      loginPasswordInput.value = ''
      ruleForm.value.loginPassword = ''
      regPasswordKey.value++
    }
  }, 100)
}

// 确认密码输入框焦点处理
const handleRegConfirmPasswordFocus = () => {
  // 只在获得焦点时且明显是浏览器自动填充的情况下清除
  // 清理之前的定时器
  if (confirmPasswordFocusTimeoutId) {
    clearTimeout(confirmPasswordFocusTimeoutId)
  }
  confirmPasswordFocusTimeoutId = setTimeout(() => {
    const passwordInputs = document.querySelectorAll('input[type="password"]')
    const confirmPasswordInput = passwordInputs[1] as HTMLInputElement
    if (confirmPasswordInput && confirmPasswordInput.value &&
      !ruleForm.value.confirmPassword &&
      confirmPasswordInput.value.length > 20 && // 提高阈值，只清除明显异常长的自动填充
      // 确保是刚获得焦点且之前Vue数据为空
      confirmPasswordInput === document.activeElement) {
      // 只清除明显的浏览器自动填充
      confirmPasswordInput.value = ''
      ruleForm.value.confirmPassword = ''
      regConfirmPasswordKey.value++
    }
  }, 100)
}


</script>
<template>
  <div class="login flex flex-col items-center px-[56px] py-[49px] overflow-auto min-h-[300px]">
    <template v-if="isReg">
      <div class="flex justify-between align-center w-full mb-[20px]">
        <div class="font-semibold text-[26px]">{{ titleTxt }}</div>
        <el-button @click="toLogin" link type="primary">{{ $t('register.goToLogin') }}</el-button>
      </div>
      <el-form ref="formRef" class="w-[100%]" :model="ruleForm" :rules="rules" label-position="left" autocomplete="off"
        data-lpignore="true" data-1p-ignore="true" :key="formKey">
        <!-- 隐藏的假输入框来误导浏览器 -->
        <input type="text" style="position: absolute; left: -9999px; width: 1px; height: 1px;" name="username"
          autocomplete="username" tabindex="-1" value="" />
        <input type="password" style="position: absolute; left: -9999px; width: 1px; height: 1px;" name="password"
          autocomplete="current-password" tabindex="-1" value="" />
        <input type="email" style="position: absolute; left: -9999px; width: 1px; height: 1px;" name="email"
          autocomplete="email" tabindex="-1" value="" />

        <el-form-item prop="phone">
          <el-input v-model="ruleForm.phone" size="large" maxlength="11"
            :placeholder="$t('common.inputPhTxt', [$t('common.phoneTxt')])" autocomplete="off" name="register-phone"
            data-lpignore="true" data-1p-ignore="true" />
        </el-form-item>
        <el-form-item prop="phoneCode">
          <!-- 语音验证码和手机验证码 -->
          <el-input v-model="ruleForm.phoneCode" size="large" :placeholder="codeInputPlaceholder" minlength="3"
            maxlength="10" autocomplete="one-time-code" :name="`verification-code-${Date.now()}`" data-lpignore="true"
            data-1p-ignore="true" data-form-type="verification" inputmode="numeric" pattern="[0-9]*" spellcheck="false"
            @focus="handleCodeFocus" @input="handleCodeInput">
            <template #append>
              <Code @get-code="getCode" :authCode="ruleForm.phone" :codeName="codeBtnName" ref="codeRef"></Code>
            </template>
          </el-input>
          <p v-if="ruleForm.phone" class="text-[12px] text-[#909399] h-[10px] w-full text-right">
            <template v-if="!isVoiceCode">
              {{ $t('login.noSmsCode') }}<span class="text-[#0067D1] cursor-pointer"
                @click.stop="getVoiceCode(true, $event)">
                {{ $t('login.voiceLogin') }}</span>
            </template>
            <template v-else>
              <span class="text-[#0067D1] cursor-pointer" @click.stop="getVoiceCode(false, $event)">{{
                $t('login.switchSmsCode') }}</span>
            </template>
          </p>
        </el-form-item>
        <el-form-item prop="loginPassword">
          <el-input v-model="ruleForm.loginPassword" size="large" minlength="8" maxlength="16" type="password"
            show-password :placeholder="$t('common.inputPhTxt', [$t('login.password')])" autocomplete="off"
            :name="`reg-pwd-${Math.random().toString(36).substring(2, 15)}`" data-lpignore="true" data-1p-ignore="true"
            data-form-type="search" @focus="handleRegPasswordFocus" :key="regPasswordKey" />
        </el-form-item>
        <el-form-item prop="confirmPassword">
          <el-input v-model="ruleForm.confirmPassword" size="large" type="password" minlength="8" maxlength="16"
            show-password :placeholder="$t('common.inputPhTxt', [$t('register.confirmPassword')])" autocomplete="off"
            :name="`reg-confirm-pwd-${Math.random().toString(36).substring(2, 15)}`" data-lpignore="true"
            data-1p-ignore="true" data-form-type="search" @focus="handleRegConfirmPasswordFocus"
            :key="regConfirmPasswordKey" />
        </el-form-item>
      </el-form>
      <div class="register pt-[15px] pb-[8px] w-[100%]">
        <el-button class="w-[100%]" @click="register" size="large" type="primary" :disabled="isDisabled">
          <span class="text-[#fff]">{{ activeType === 'register' ? $t('register.registerButton') :
            $t('common.submitTxt')
            }}</span>
        </el-button>
      </div>
      <div v-if="activeType === 'register'" class="w-[100%] text-[12px] text-[#909399]">
        <el-checkbox v-model="trustPact" size="large" class="align-middle" />
        <span class="align-middle">
          <span class="ml-[6px]">{{ $t('register.agreementPrefix') }}</span><span class="ys"
            @click="openAgreementDialog">{{
              $t('register.userAgreement') }}</span><span>{{ $t('register.and') }}</span>
          <span class="ys" @click="openPrivacyDialog">{{ $t('register.privacyPolicy') }}</span>
        </span>
      </div>
    </template>
    <template v-else>
      <img :src="regSucess" alt="" class="w-[152px]">
      <p class="text-[30px] text-[#191919] font-[500] pt-[33px] pb-[11px]">{{ $t('register.congratulations') }}</p>
      <p class="pb-[54px]"><span class="jump">{{ timeLeft }}s</span>{{ $t('register.autoRedirectText') }}</p>
      <el-button type="primary" class="h-[40px] w-[200px]" @click="toHome(LOGIN_PATH)">{{
        $t('register.goToHomepage') }}</el-button>
    </template>

    <!-- 通用弹窗 -->
    <el-dialog v-model="showDialog"
      :title="dialogType === 'agreement' ? $t('register.userAgreement') : $t('register.privacyPolicy')" width="800px"
      @close="closeDialog">
      <div class="dialog-content h-[550px] overflow-y-auto px-[30px] pb-[50px]">
        <!-- 使用协议内容 -->
        <div v-if="dialogType === 'agreement'" v-html="agreementContent"></div>
        <!-- 隐私政策内容 -->
        <div v-else-if="dialogType === 'privacy'" v-html="privacyContent"></div>
      </div>
    </el-dialog>
    <SliderDialog v-model:visible="sliderDialogVisible" ref="sliderDialogRef" :phone="ruleForm.phone"
      @verify-success="handleVerifySuccess" />
  </div>
</template>
<style lang="less" scoped>
.ys {
  color: var(--el-color-primary) !important;
  cursor: pointer;
  font-weight: 700;
}

.jump {
  color: var(--el-color-primary) !important;
}

/* 1420px屏幕自适应高度 */
@media (min-width: 1420px) {
  .dialog-content {
    height: calc(100vh - 250px) !important;
    max-height: 700px !important;
  }
}
</style>
